package com.johnrambo.ktea.base

import android.app.Activity
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.TypedArray
import android.os.Build
import android.os.Bundle
import android.os.Handler
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.GenericLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import com.johnrambo.ktea.Settings
import com.johnrambo.ktea.common.createLoadingDialog
import com.johnrambo.ktea.common.createLoadingDialog2
import com.johnrambo.ktea.common.delayUI
import com.johnrambo.ktea.net.http.TokenLose
import com.johnrambo.ktea.rxbus.RxBus
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.coroutines.Job
import java.util.concurrent.TimeUnit

/**
 * Create by JohnRambo at 2018/7/31
 */
abstract class BaseActivity : AppCompatActivity() {

//    private val loadingView by lazy { createLoadingViewInFrameLayout(this) }

    protected val jobs by lazy { mutableListOf<Job>() }
    protected val disposables by lazy { CompositeDisposable() }
    open protected var loadingMilliSeconds = 0L
    var mContext: BaseActivity? = null
    @Volatile
    private var showLoadingTimes = 0

    private val loadingProgress by lazy {
        createLoadingDialog(this) { showLoadingTimes = 0 }
    }
    private val loadingProgress2 by lazy {
        createLoadingDialog2(this) { showLoadingTimes = 0 }
    }
    companion object {
        val loginObservable by lazy {
            RxBus.BUS.toObservable(TokenLose::class.java)
                    .throttleFirst(10, TimeUnit.SECONDS)
                    .observeOn(AndroidSchedulers.mainThread())!!
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Settings.activityStack().add(this)

        mContext = this

        disposables.add(
                loginObservable.subscribe { tokenLoseDoing() }
        )
        //如果是8.0系统的手机，并且认为是透明主题的Activity
        if (Build.VERSION.SDK_INT == 26 && this.isTranslucentOrFloating()) {
            //通过反射取消方向的设置，这样绕开系统的检查，避免闪退
            val result: Boolean = this.fixOrientation()
        }
    }

    // 显示加载框
    fun showLoading() {
        ++showLoadingTimes
        if (!loadingProgress.isShowing) {
            loadingProgress.show()
        }
//        loadingView.visibility = View.VISIBLE
    }

    // 关闭加载框
    fun dismissLoading() {
        if (showLoadingTimes > 0) {
            --showLoadingTimes
        }
        if (showLoadingTimes == 0) {
            if (loadingProgress.isShowing) delayUI(loadingMilliSeconds) {
                if (loadingProgress.isShowing) loadingProgress.dismiss()
            }
        }
//        loadingView.visibility=View.GONE
    }

    // 显示加载框
    fun showLoading2() {
        ++showLoadingTimes
        if (!loadingProgress2.isShowing) {
            loadingProgress2.show()
        }
//        loadingView.visibility = View.VISIBLE
    }

    // 关闭加载框
    fun dismissLoading2() {
        if (showLoadingTimes > 0) {
            --showLoadingTimes
        }
        if (showLoadingTimes == 0) {
            if (loadingProgress2.isShowing) delayUI(loadingMilliSeconds) {
                if (loadingProgress2.isShowing) loadingProgress2.dismiss()
            }
        }
//        loadingView.visibility=View.GONE
    }

    /**
     * token丢失时需要要做的事情
     */
    open fun tokenLoseDoing() = Unit

    //通过反射判断是否是透明页面
     open fun isTranslucentOrFloating(): Boolean {
        var isTranslucentOrFloating = false
        try {
            val styleableRes =
                Class.forName("com.android.internal.R\$styleable")
                    .getField("Window")[null] as IntArray
            val ta = obtainStyledAttributes(styleableRes)
            val m = ActivityInfo::class.java.getMethod(
                "isTranslucentOrFloating",
                TypedArray::class.java
            )
            m.isAccessible = true
            isTranslucentOrFloating = m.invoke(null, ta) as Boolean
            m.isAccessible = false
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return isTranslucentOrFloating
    }

    //通过反射将方向设置为 SCREEN_ORIENTATION_UNSPECIFIED，绕开系统的检查
     open fun fixOrientation(): Boolean {
        try {
            val field =
                Activity::class.java.getDeclaredField("mActivityInfo")
            field.isAccessible = true
            val o =
                field[this] as ActivityInfo
            o.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
            field.isAccessible = false
            return true
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return false
    }
    override fun onDestroy() {
        if (loadingProgress.isShowing) {
            loadingProgress.cancel()
        }
        if (loadingProgress2.isShowing) {
            loadingProgress2.cancel()
        }
        /*with(window.decorView) {
            this as FrameLayout
            removeView(loadingView)
        }*/
        Settings.activityStack().remove(this)
        disposables.clear()
        super.onDestroy()
    }

}